package com.foreveross.bsl.mam.app.web;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.foreveross.bsl.file.storage.FileStorage;
import com.foreveross.bsl.file.storage.FileStorageFactory;
import com.foreveross.bsl.mam.app.application.AppMainApplication;
import com.foreveross.bsl.mam.app.application.AppVersionApplication;
import com.foreveross.bsl.mam.app.application.AppVersionWidgetVersionApplication;
import com.foreveross.bsl.mam.app.application.DefindApplication;
import com.foreveross.bsl.mam.app.application.vo.AppMainVo;
import com.foreveross.bsl.mam.app.application.vo.AppVersionVo;
import com.foreveross.bsl.mam.app.application.vo.AppVersionWidgetVersionVo;
import com.foreveross.bsl.mam.model.application.AttachmentApplication;
import com.foreveross.bsl.mam.model.application.vo.AttachmentVO;
import com.foreveross.bsl.system.application.ApplicationRegisterApplication;

/**
 * 应用类别操作类
 * 
 * @author tanzhixiong
 * @2013-6-22 @下午3:01:42
 */
@Controller
@RequestMapping("/mam/appversions")
public class AppVersionCountroller extends AppBaseController {

	@Inject
	private AppVersionApplication appVersionApplication;

	@Inject
	private AppMainApplication appMainApplication;

	@Inject
	private AttachmentApplication attachmentApplication;
	@Inject
	private AppVersionWidgetVersionApplication appVersionWidgetVersionApplication;
	@Inject
	private ApplicationRegisterApplication applicationRegisterApplication;
	@Inject
	private DefindApplication defindApplication;

	private ResourceBundle rb = ResourceBundle.getBundle("config");

	@RequestMapping(value = "/{platform}/list", method = RequestMethod.GET)
	public String list(@PathVariable("platform") String platform,
			@RequestParam("appId") String appId, Model model) {
		List<AppVersionVo> list = appVersionApplication.findByPlatform(platform, appId);
		model.addAttribute("appId", appId);
		model.addAttribute("platform", platform);
		model.addAttribute("list", list);
		return "app/appVersion-list";
	}

	@RequestMapping(value = "/{platform}", method = RequestMethod.GET)
	public String appVersion(@PathVariable("platform") String platform,
			@RequestParam("appId") String appid, Model model) {
		AppMainVo appvo = appMainApplication.getEntity(appid);
		model.addAttribute("appvo", appvo);
		model.addAttribute("platform", platform);
		List<AppVersionVo> list = appVersionApplication.findByPlatform(
				platform, appid);
		if (list != null && list.size() > 0) {
			model.addAttribute("lastVersion", list.get(0));
		}
		return "app/appVersion-add";
	}

	/**
	 * 保存平台的版本
	 * 
	 * @param appVersionVo
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/{platform}", method = RequestMethod.POST)
	public Map<String, String> add(@PathVariable("platform") String platform,
			AppVersionVo appversion, HttpServletRequest request) {

		Map<String, String> result = new HashMap<String, String>();
		try {
			AppVersionVo appv = appVersionApplication.findByVersion(platform,
					appversion.getApplicationid(), appversion.getVersion());
			Date date = new Date();
			if (appv == null) {//
				if (StringUtils.isNotEmpty(appversion.getBundle())) {
					if ("ios".equals(platform)) {
						String plist = this.createPlist(request,
								appversion.getApplicationid(),
								appversion.getBundle());
						appversion.setPlist(plist);
					}
				}
				appversion.setAvailable("1");
				appversion.setCreate_time(date);
				appversion.setModified_time(date);
				appVersionApplication.saveEntity(appversion);
				result.put("result", "success");
				result.put("statusCode", "1");
			} else {
				result.put("result", "success");
				result.put("statusCode", "0");
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.put("result", "error");
		}
		return result;
	}

	/**
	 * 进入版本详情页面
	 * 
	 * @param appid
	 * @param version
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/{platform}/{id}", method = RequestMethod.GET)
	public String view(@PathVariable("platform") String platform, @PathVariable("id") String id, Model model, 
			HttpServletRequest request) {
		AppVersionVo versionVo = this.appVersionApplication.getEntity(id); 	// 获取当前应用的版本
		if (StringUtils.isNotEmpty(versionVo.getPlist()) && "ios".equals(platform)) {
			model.addAttribute("plist", versionVo.getPlist());
		}
		model.addAttribute("appVersion", versionVo);
		AppMainVo appvo = this.appMainApplication.getEntity(versionVo.getApplicationid());
		model.addAttribute("appvo", appvo);
		String appKey = this.applicationRegisterApplication.getAppKeyByAppId(versionVo.getApplicationid());
		model.addAttribute("appKey", appKey);
		return "app/appVersion-view";
	}

	/**
	 * 进入新建版本编辑页面
	 * 
	 * @param appid
	 * @param version
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/{platform}/{version}/{id}", method = RequestMethod.GET)
	public String edit(@PathVariable("id") String id, Model model) {
		// 获取当前应用的版本
		AppVersionVo appVersion = appVersionApplication.getEntity(id);
		model.addAttribute("appVersion", appVersion);
		AppMainVo appvo = appMainApplication.getEntity(appVersion
				.getApplicationid());
		model.addAttribute("appvo", appvo);
		return "app/appVersion-edit";
	}

	/**
	 * 修改平台版本
	 * 
	 * @param appVersionVo
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/{platform}/{version}/{id}", method = RequestMethod.POST)
	public Map<String, String> versionUpdate(@PathVariable("id") String id,
			AppVersionVo appVersionVo) {
		Map<String, String> result = new HashMap<String, String>();
		try {

			AppVersionVo appv = appVersionApplication.getEntity(id);
			Date date = new Date();
			appv.setRelease_note(appVersionVo.getRelease_note());
			appv.setModified_time(date);
			appVersionApplication.updateEntity(appv.getId(), appv);
			result.put("result", "success");
		} catch (Exception e) {
			e.printStackTrace();
			result.put("result", "error");
		}
		return result;
	}

	/**
	 * 应用下架
	 * 
	 * @param appMainVo
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/offline/{platform}/{id}", method = RequestMethod.PUT)
	public Map<String, String> appDown(
			@PathVariable("platform") String platform,
			@PathVariable("id") String id) {
		Map<String, String> result = new HashMap<String, String>();
		try {

			// 根据应用ID 查询出上架应用版本列表
			AppVersionVo versionVo = appVersionApplication.getEntity(id);
			versionVo.setStatus(5);// 下架状态
			versionVo.setModified_time(new Date());
			appVersionApplication.updateEntity(versionVo.getId(), versionVo);
			result.put("result", "success");
		} catch (Exception e) {
			e.printStackTrace();
			result.put("result", "error");
		}
		return result;
	}

	/**
	 * 应用上架
	 * 
	 * @param appMainVo
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/online/{platform}/{id}", method = RequestMethod.PUT)
	public Map<String, String> appPublish(
			@PathVariable("platform") String platform,
			@PathVariable("id") String id) {
		Map<String, String> result = new HashMap<String, String>();
		try {
			AppVersionVo versionVo = appVersionApplication.getEntity(id);
			List<AppVersionVo> onlineList = appVersionApplication.getAppStatus(
					versionVo.getApplicationid(), 4);// 查询上架版本
			if (onlineList != null) {
				for (AppVersionVo onlineVo : onlineList) {
					if (platform.equals(onlineVo.getPlatformid())) {
						onlineVo.setStatus(5);
						onlineVo.setModified_time(new Date());
						appVersionApplication.updateEntity(onlineVo.getId(),
								onlineVo);// 先将架上版本进行下架
						break;
					}
				}
			}
			// 进行上架操作
			if (versionVo.getStatus() == 3 || versionVo.getStatus() == 5) { // 已打包或者已下架，则进行上架
				versionVo.setStatus(4);
				versionVo.setModified_time(new Date());
				appVersionApplication
						.updateEntity(versionVo.getId(), versionVo);
			}
			result.put("result", "success");
		} catch (Exception e) {
			e.printStackTrace();
			result.put("result", "error");
		}
		return result;
	}

	//
	// /**
	// * 异步获取版本信息
	// *
	// * @param model
	// * @param id
	// * @return
	// */
	// @ResponseBody
	// @RequestMapping("/ajaxVersion-view/{id}")
	// public AppVersionVo ajaxVersion(@PathVariable String id) {
	// AppVersionVo appVersion = appVersionApplication.getEntity(id);
	// return appVersion;
	// }

	/**
	 * 此版本版是否存在
	 * 
	 * @param model
	 * @param id
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/checkappVersion/{id}")
	public Map<String, String> checkappVersion(@PathVariable String id,
			@RequestParam("version") String version) {
		Map<String, String> result = new HashMap<String, String>();
		List<AppVersionVo> appVersionList = appVersionApplication
				.findListByVersion(id, version);
		if (appVersionList != null && appVersionList.size() > 0) {
			result.put("result", "1");
		} else {
			result.put("result", "0");
		}
		return result;
	}

	/**
	 * 删除应用版本
	 * 
	 * @param appId
	 * @param versionId
	 * 
	 * @return Map<String,Object>
	 */
	@ResponseBody
	@RequestMapping(value = "/{platform}/{version}/{id}", method = RequestMethod.DELETE)
	public Map<String, Object> deleteAppVersion(@PathVariable("id") String id) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			result.put("hasPub", "false");
			AppVersionVo appVersionVo = appVersionApplication.getEntity(id);
			if (appVersionVo.getStatus() == 4) {// 首先查询是否为已上架的版本
				result.put("hasPub", "true");
				return result;
			}

			// 删除该版本与模块的关联关系
			appVersionWidgetVersionApplication.deleteByAppVersion(
					appVersionVo.getPlatformid(), appVersionVo.getVersion(),
					appVersionVo.getApplicationid());
			// 删除该版本
			appVersionApplication.deleteEntity(appVersionVo.getId());
			// 删除该版本个性化信息
			defindApplication.deleteByAppId(appVersionVo.getPlatformid(),
					appVersionVo.getVersion(), appVersionVo.getApplicationid());
			result.put("result", "success");
		} catch (Exception e) {
			e.printStackTrace();
			result.put("result", "error");
		}
		return result;
	}

	@RequestMapping(value = "/{platform}/clone/{cloneId}", method = RequestMethod.GET)
	public String enterClone(@PathVariable("platform") String platform,
			@PathVariable("cloneId") String cloneId,
			@RequestParam("appId") String appId, Model model) {
		AppMainVo appvo = appMainApplication.getEntity(appId);
		model.addAttribute("appMainVo", appvo);
		AppVersionVo vo = appVersionApplication.getEntity(cloneId);
		model.addAttribute("cloneVo", vo);
		return "app/appClone-modal";
	}

	/**
	 * 克隆应用版本
	 * 
	 * @param appVersionVo
	 * 
	 * @return Map<String, String>
	 */
	@ResponseBody
	@RequestMapping(value = "/{platform}/clone", method = RequestMethod.POST)
	public Map<String, Object> cloneAppVersion(
			@PathVariable("platform") String platform, String cloneId,
			String newVersion, String build, String note) {
		Map<String, Object> _result = new HashMap<String, Object>();
		try {
			// 1. 获取要克隆的应用版本信息
			AppVersionVo vo = appVersionApplication.getEntity(cloneId);
			// 2. 克隆
			if (vo == null) {
				_result.put("result", "false");
				_result.put("msg", "没有找到该版本信息！");
				return _result;
			}
			// 判断是否已存在对应的版本
			AppVersionVo ver = appVersionApplication.findByVersion(platform,
					vo.getApplicationid(), newVersion);
			if (ver != null) {
				_result.put("result", "false");
				_result.put("msg", "版本号已存在");
				return _result;
			}

			// 判断构建号是否合法
			int[] checkResult = appVersionApplication.checkBuild(platform,
					build, vo.getApplicationid());
			if (checkResult[0] == 0) {
				_result.put("result", "false");
				_result.put("msg", "构建号必须大于" + checkResult[1]);
				return _result;
			}

			AppVersionVo appVersionNew = new AppVersionVo();
			Date date = new Date();
			appVersionNew.setVersion(newVersion);
			appVersionNew.setApplicationid(vo.getApplicationid());
			appVersionNew.setPlatformid(vo.getPlatformid());
			appVersionNew.setAvailable("1");
			appVersionNew.setStatus(1);
			appVersionNew.setCreate_time(date);
			appVersionNew.setModified_time(date);
			appVersionNew.setRelease_note(note);
			appVersionNew.setBuild(Integer.valueOf(build));
			appVersionNew.setSnapshotIds(vo.getSnapshotIds());
			AppVersionVo cloneObj = appVersionApplication
					.saveEntity(appVersionNew);
			_result.put("cloneObj", cloneObj);
			// 3. 克隆与模块的关联关系
			List<AppVersionWidgetVersionVo> versionWidgetVersions = appVersionWidgetVersionApplication
					.getListByPlatEntity(platform, vo.getVersion(),
							vo.getApplicationid());

			if (null != versionWidgetVersions
					&& !versionWidgetVersions.isEmpty()) {
				AppVersionWidgetVersionVo awvo = null;
				List<AppVersionWidgetVersionVo> list = new ArrayList<AppVersionWidgetVersionVo>();
				for (AppVersionWidgetVersionVo widgetVersion : versionWidgetVersions) {
					awvo = new AppVersionWidgetVersionVo();
					awvo.setPlatform(platform);
					awvo.setAppId(widgetVersion.getAppId());
					awvo.setWidgetId(widgetVersion.getWidgetId());
					awvo.setWidgetVersion(widgetVersion.getWidgetVersion());
					awvo.setAppVersion(newVersion);
					list.add(awvo);
				}
				appVersionWidgetVersionApplication.saveEntities(list);
			}
			_result.put("result", "success");
		} catch (Exception e) {
			e.printStackTrace();
			_result.put("result", "false");
			_result.put("msg", "发生异常，请稍后再试！");
		}

		return _result;
	}

	/**
	 * 添加快照
	 * 
	 * @param appVersionVo
	 * 
	 * @return Map<String, String>
	 */
	@ResponseBody
	@RequestMapping(value = "/{platform}/snapshot", method = RequestMethod.POST)
	public Map<String, Object> addAppSnapshot(String appVId, String attchmentId) {
		Map<String, Object> _result = new HashMap<String, Object>();
		try {
			appVersionApplication.addAppSnapshot(appVId, attchmentId);
			_result.put("result", "success");
		} catch (Exception e) {
			_result.put("result", "false");
			_result.put("msg", "添加快照失败!");
			e.printStackTrace();
		}
		return _result;
	}

	/**
	 * 删除应用版本快照
	 * 
	 * @param appId
	 * @param versionId
	 * 
	 * @return Map<String,Object>
	 */
	@ResponseBody
	@RequestMapping(value = "/{platform}/snapshot/{snapshotId}", method = RequestMethod.DELETE)
	public Map<String, Object> deleteAppSnapshot(
			@PathVariable("snapshotId") String snapshotId,
			@RequestParam("appVId") String appVId) {
		Map<String, Object> _result = new HashMap<String, Object>();
		try {
			appVersionApplication.deleteSnapshot(appVId, snapshotId);
			_result.put("result", "success");
		} catch (Exception e) {
			_result.put("result", "false");
			_result.put("msg", "删除快照失败！");
			e.printStackTrace();
		}

		return _result;
	}

	/**
	 * 生成plist
	 * 
	 * @param request
	 * @param appId
	 * @param bundle
	 * @return
	 */
	private String createPlist(HttpServletRequest request, String appId, String bundle) {
		// 生成plist
		try {
			String basePath = request.getScheme() + "://"
					+ request.getServerName() + ":" + request.getServerPort()
					+ request.getContextPath();
			AppMainVo appMain = appMainApplication.getEntity(appId);
			// 新增配置文件，可以支持使用http代理请求后台时候，生成plist文件下载地址
			String plistURL = rb.getString("plistURL");
			if (StringUtils.isNotEmpty(plistURL) && plistURL.startsWith("http")) {
				basePath = plistURL;
			}
			String url = basePath + "/mam/attachment/download/" + bundle;
			String plistStr = this.getPlistTemplate();
			if (plistStr != null) {
				plistStr = plistStr.replaceAll("\\{bundle-identifier\\}",
						appMain.getIdentifier());
				plistStr = plistStr.replaceAll("\\{subtitle\\}",
						appMain.getApp_name());
				plistStr = plistStr.replaceAll("\\{title\\}",
						appMain.getApp_name());
				plistStr = plistStr.replaceAll("\\{url\\}", url);
			}

			String filename = appMain.getIdentifier() + ".plist";
			FileStorageFactory f = FileStorageFactory.getInstance();
			FileStorage fs = f.getFileStorage();
			String plistId = fs.saveFile(plistStr.getBytes("utf-8"), null, null);
			AttachmentVO entity = new AttachmentVO();
			Date date = new Date();
			entity.setAvailable(1);
			entity.setContentType("application/octet-stream");
			entity.setCreatedAt(date);
			entity.setModifiedAt(date);
			entity.setUploadFilename(filename);
			entity.setSize(plistStr.length());
			// 保存到云服务
			entity.setLocalFilename(plistId);
			AttachmentVO resultVo = attachmentApplication.saveEntity(entity);
			return resultVo.getId();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * plist 模板
	 * 
	 * @return
	 */
	private String getPlistTemplate() {
		InputStream is = AppVersionCountroller.class.getResourceAsStream("/template.plist");
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		int i = -1;
		try {
			while ((i = is.read()) != -1) {
				baos.write(i);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		String tempString = baos.toString();
		return tempString;
	}
}
